<template>
  <div>
    <el-upload action :on-change="handleChange" :auto-upload="false" :show-file-list="false">
      <el-button class="el-button el-button--primary" :size="size">
        上传
        <i class="el-icon-upload el-icon--right"></i>
      </el-button>
    </el-upload>
    <span v-if="!miniList && enableList">
      <div v-if="count_upload.total > 0" class="filelist-panel">
        <el-scrollbar style="height: 100%;">
          <el-row class="row-list" v-for="(item,index) in files" :key="index">
            <el-col :span="8">
              <div style="white-space:nowrap;text-overflow:ellipsis;overflow:hidden;">
                <a href="javascript:void(0);">{{ item.name }}</a>
              </div>
            </el-col>
            <el-col :span="1">
              <i v-if="item.parse < 100" class="el-icon-loading"></i>
            </el-col>
            <el-col :span="12">
              <span v-if="Math.round(Number(item.progress)) >= 100">
                <el-progress :percentage="Number(item.progress.toFixed(0))" status="success"></el-progress>
              </span>
              <span v-else>
                <el-progress :percentage="Number(item.progress.toFixed(0))"></el-progress>
              </span>
            </el-col>
            <el-col :span="1">
              <span v-if="Math.round(Number(item.progress)) >= 100">
                <a
                  :href="apiUrl + '/api/v1/downloader/stream/' + encodeURI(item.name) +'?hash=' + item.hash"
                >
                  <i class="el-icon-share"></i>
                </a>
              </span>
            </el-col>
          </el-row>
        </el-scrollbar>
        <div class="close-btn">
          <a @click="toMini()" style="font-size: 24px;">
            <i class="el-icon-close"></i>
          </a>
        </div>
      </div>
    </span>
    <span v-else-if="miniList && enableList">
      <div class="mini-panel">
        <el-badge :value="count_upload.total" class="item">
          <a>文件数</a>
        </el-badge>
        <el-badge :value="count_upload.parse" class="item" type="warning">
          <a>解析中</a>
        </el-badge>
        <el-badge :value="count_upload.uploading" class="item">
          <a>上传中</a>
        </el-badge>
        <el-badge :value="count_upload.uploaded" class="item" type="primary">
          <a>已完成</a>
        </el-badge>
        <div class="close-btn">
          <a @click="toLarge()" style="font-size: 24px;">
            <i class="el-icon-arrow-up"></i>
          </a>
        </div>
      </div>
    </span>
    <span v-else>
      <div></div>
    </span>
  </div>
</template>
<script>
import Vue from "vue";
import axios from "axios";
import sha1 from "js-sha1";
import { getEtag } from "./qetag.js";
import fileinfo from "./fileinfo.js";
import _ from "underscore";
export default {
  name: "elsimupload",
  props: {
    apiUrl: { type: String, required: true },
    autoUpload: { type: Boolean, default: true },
    enableList: { type: Boolean, default: true },
    size: { type: String, default: "small" }
  },
  data: function() {
    return {
      miniList: false,
      uplist: {},
      files: {}
    };
  },
  computed: {
    count_upload: {
      get: function() {
        let [total, parse, uploading, uploaded] = [0, 0, 0, 0];
        if (this.files) {
          for (let key in this.files) {
            total++;
            if (this.files[key].progress >= 100) {
              uploaded++;
            }
            if (this.files[key].parse < 100) {
              parse++;
            }
            if (
              this.files[key].progress < 100 &&
              this.files[key].parse >= 100
            ) {
              uploading++;
            }
          }
        }
        return {
          total: total,
          parse: parse,
          uploading: uploading,
          uploaded: uploaded
        };
      },
      set: function() {}
    }
  },
  mounted() {},
  methods: {
    toMini() {
      this.miniList = true;
    },
    toLarge() {
      this.miniList = false;
    },
    handleChange(file) {
      Vue.set(this.files, file.name, new fileinfo(file.name));
      Vue.set(this.uplist, file.name, file);
      if (this.autoUpload) {
        this.startUpload(file);
      } else {
        this.$emit("beforeUpload", file);
      }
    },
    startUpload(file) {
      let self = this;
      getEtag(
        sha1,
        null,
        file.raw,
        function(hash) {
          self.files[file.name].hash = hash;
          self.checkFile(file.raw, hash);
        },
        self.ParseProgress
      );
    },
    ParseProgress(evt) {
      let reader = evt.currentTarget;
      this.files[reader.name].parse += 100 / reader.count;
    },
    checkFile(file, hash) {
      let self = this;
      axios
        .get(this.apiUrl + "/api/v1/uploader/chkfile", {
          params: {
            fkey: file.name,
            hash: hash
          }
        })
        .then(res => {
          console.log(res.data);
          if (res.data) {
            self.uploadFile(file, hash);
          } else {
            self.files[file.name].progress = 100;
            self.$emit("onUploaded", self.files[file.name]);
            delete self.uplist[file.name];
          }
        })
        .catch(error => {
          self.$message.error("文件效验出错!");
        });
    },
    uploadFile(file, hash) {
      let self = this;
      let formData = new FormData();
      formData.append("file", file);
      formData.append("hash", hash);
      let config = {
        headers: {
          "Content-Type": "multipart/form-data"
        },
        onUploadProgress: progressEvent => {
          self.files[file.name].progress =
            (progressEvent.loaded / progressEvent.total) * 100;
        }
      };
      axios
        .post(this.apiUrl + "/api/v1/uploader/file", formData, config)
        .then(res => {
          self.$emit("onUploaded", self.files[file.name]);
          delete self.uplist[file.name];
        })
        .catch(error => {
          self.$message.error("文件上传出错!");
        });
    }
  }
};
</script>

<style scoped>
.filelist-panel {
  width: 400px;
  height: 200px;
  position: fixed;
  bottom: 5px;
  right: 5px;
  font-size: 14px;
  display: block;
  padding: 30px 5px 15px 20px;
  overflow-x: hidden;
  border-width: 1px;
  border-style: solid;
  box-sizing: border-box;
  border-color: #dfdfdf;
  background-color: #f5f5f5;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
}

.el-scrollbar__wrap {
  overflow-x: hidden;
}

.mini-panel {
  width: 400px;
  height: 40px;
  position: fixed;
  bottom: 5px;
  right: 5px;
  font-size: 14px;
  text-align: center;
  display: block;
}

.close-btn {
  position: absolute;
  top: 2px;
  right: 5px;
  cursor: pointer;
}

a {
  font-size: 12px;
  text-decoration: none;
  line-height: 25px;
  color: #000000;
}

.row-list {
  border-bottom: #606266;
  line-height: 20px;
  border: 0;
  border-bottom: 1px dashed #ccc;
  padding: 5px 0 5px 0;
}

.item {
  padding-left: 5px;
  margin-top: 15px;
  margin-right: 30px;
}

.el-dialog__body {
  padding: 15px 20px;
  color: #606266;
  font-size: 14px;
}
</style>